# -*- coding: utf-8 -*-

import json
import logging

from django.views.generic import TemplateView
from django.utils.decorators import method_decorator
from django.views.decorators.http import require_POST, require_GET
from django.utils.encoding import smart_unicode
from common.order import db as order_db
from common.bank_record import db as bankrecord_db
from common.order.model import PAY_STATUS
from common.order import handler as order_handler
from common.mch import db as mch_db
from common.mch import handler as mch_handler
from common.utils.export import redirect_to_file, gen_filename
from common.utils.decorator import response_wrapper
from common.utils.api import token_required
from common.utils.tz import (
    utc_to_local_str,
    ts_to_local_date_str
)
from common.admin import db as user_db

_LOGGER = logging.getLogger('hydra')


class OrderView(TemplateView):
    def get(self, req):
        query_dct = req.GET.dict()
        ex_amount = []
        if 'exact_amount' in query_dct:
            query_dct['real_amount'] = query_dct['exact_amount']
            ex_amount = ['exact_amount']
            del query_dct['exact_amount']
        from admin.views import add_query_fliter
        if 'mch_id' not in query_dct:
            add_query_fliter(req, query_dct)
        _LOGGER.info('OrderView get orders: %s, ', query_dct)
        items, total_count = order_db.list_order(query_dct)
        mch_names = mch_db.get_mch_name_dict()
        resp_items = []
        for item in items:
            data = item.as_dict()
            data['collection_amount'] = data['real_amount']
            if data['status'] <> PAY_STATUS.MANUAL_SUCC and data['status'] <> PAY_STATUS.SUCC:
                data['real_amount'] = 0
            data['id'] = str(data['id'])
            data['mch_id'] = mch_names[data['mch_id']]
            data['created_at'] = utc_to_local_str(data['created_at'])
            data['updated_at'] = utc_to_local_str(data['updated_at'])
            data['payed_at'] = utc_to_local_str(data['payed_at']) if data['payed_at'] else ''
            resp_items.append(data)

        total_fee, real_amount, exact_amount, success_rate, record_id_stats = order_db.get_order_overview(query_dct)
        calc_succ_rate = float(total_count) + 0.00
        if success_rate != 0 and calc_succ_rate != 0:
            calc_succ_rate = success_rate / calc_succ_rate
        else:
            calc_succ_rate = 0
        return {'list':  resp_items, 'page': query_dct.get('$page', 1),
                'size': len(resp_items), 'total_count': total_count, 'total_fee': total_fee, 'exact_amount': exact_amount,
                'success_rate': calc_succ_rate * 100, 'record_id_stats': record_id_stats,
                'real_amount': real_amount}

    def put(self, req, order_id): 
        _LOGGER.info('Update order: %s', req.body)        
        params = json.loads(smart_unicode(req.body)) 

        user = user_db.get_user(int(req.user_id))
        if not user:
            raise err.ResourceNotFound('req.user_id {} not found'.format(req.user_id))
        
        if params is None:
            raise err.ResourceNotFound('Request data is empty')
        else:
            if order_id is not None:
                order = order_db.get_order(order_id)
                if order is not None:
                    params['operator'] = user.nickname
                    data = order_db.upsert_order(params, int(order_id))
                    if int(params['status']) == PAY_STATUS.MANUAL_SUCC or int(params['status']) == PAY_STATUS.SUCC:
                        mch_handler.notify_mch(int(order_id))
                    return data.as_dict()
                else:
                    raise err.ResourceNotFound('Order {} not found'.format(order_id))

    @method_decorator(response_wrapper)
    @method_decorator(token_required)
    def dispatch(self, *args, **kwargs):
        return super(OrderView, self).dispatch(*args, **kwargs)


@require_GET
@response_wrapper
@token_required
def get_order_detail(req, order_id):
    mch_names = mch_db.get_mch_name_dict()
    order = order_db.get_order(id=int(order_id))
    data = order.as_dict()
    data['mch_id'] = mch_names[data['mch_id']]
    try:
        extend = json.loads(data['extend'])
    except :
        extend = {}
    data['id'] = str(data['id'])
    data['handler'] = extend.get('handler', 'auto')
    data['msg'] = extend.get('msg', u'自动上分')
    data['created_at'] = utc_to_local_str(data['created_at'])
    data['updated_at'] = utc_to_local_str(data['updated_at'])
    return data


@require_POST
@response_wrapper
@token_required
def order_fresh(req):
    _LOGGER.info('order_fresh: %s', req.body)
    d = json.loads(req.body)
    mch_handler.notify_mch(int(d['id']))
    return {'id': int(d['id'])}


@require_GET
@token_required
@response_wrapper
def export_orders(req):
    query_dct = req.GET.dict()
    filename = gen_filename('order')
    header = ['id', 'mch_id', 'bankcard_name', 'bankcard_num', 'user_id',
              'out_trade_no', 'total_fee', 'real_amount',
              'record_id', 'status', 'payed_at',
              'created_at', 'updated_at']
    cn_header = [u'订单id', u'商户ID', u'银行卡名称', u'银行卡号', u'用户ID',
                 u'商户订单号', u'订单金额', u'真实金额',
                 u'银行记录id', u'订单状态',
                 u'上分时间', u'创建订单时间', u'最后修改时间']
    items, total_count = order_db.list_export_order(query_dct)
    mch_names = mch_db.get_mch_name_dict()
    resp_items = []
    for item in items:
        data = item.as_dict()
        data['id'] = str(data['id'])
        data['mch_id'] = mch_names[data['mch_id']]
        data['created_at'] = utc_to_local_str(data['created_at'])
        data['updated_at'] = utc_to_local_str(data['updated_at'])
        data['payed_at'] = utc_to_local_str(data['payed_at']) if data['payed_at'] else ''
        data['status'] = PAY_STATUS.get_label(int(data['status'] or 0))
        resp_items.append([data.get(x, '-') for x in header])
    return redirect_to_file(resp_items, cn_header, filename)


@require_POST
@response_wrapper
@token_required
def record_match_order(req):
    _LOGGER.info('record_match_order: %s', req.body)
    d = json.loads(req.body)
    user = user_db.get_user(int(req.user_id))
    operator = user.nickname
    msg = {}
    msg['msg'] = d['msg']
    msg['handler'] = req.user.nickname
    msg['handler_id'] = req.user_id
    order_handler.manual_record_order(d['record_id'], d['order_id'], json.dumps(msg), operator)
    return {'id': int(d['record_id'])}
